package mobile

import (
	"bytes"
	"crypto/aes"
	"crypto/md5"
	"crypto/sha1"
	"crypto/tls"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"encoding/xml"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net"
	"net/http"
	"net/url"
	"sort"
	"strconv"
	"strings"
	"tcsc/models"
	"tcsc/sword"
	"time"

	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	"github.com/smartwalle/alipay"
)

// "tcsc/sword"
type UnifyOrderReq struct {
	Appid            string `xml:"appid"`            //公众账号ID
	Body             string `xml:"body"`             //商品描述
	Mch_id           string `xml:"mch_id"`           //商户号
	Nonce_str        string `xml:"nonce_str"`        //随机字符串
	Notify_url       string `xml:"notify_url"`       //通知地址
	Trade_type       string `xml:"trade_type"`       //交易类型
	Spbill_create_ip string `xml:"spbill_create_ip"` //支付提交用户端ip
	Total_fee        int    `xml:"total_fee"`        //总金额
	Out_trade_no     string `xml:"out_trade_no"`     //商户订单号
	Sign             string `xml:"sign"`             //签名
	Openid           string `xml:"openid"`           //购买商品的用户wxid
	Attach           string `xml:"attach"`           //购买商品的用户wxid
	Scene_info       string `xml:"scene_info"`       //购买商品的用户wxid
	Product_id       string `xml:"product_id"`
}

type UnifyOrderResp struct {
	Return_code string `xml:"return_code"`
	Return_msg  string `xml:"return_msg"`
	Appid       string `xml:"appid"`
	Mch_id      string `xml:"mch_id"`
	Nonce_str   string `xml:"nonce_str"`
	Sign        string `xml:"sign"`
	Result_code string `xml:"result_code"`
	Prepay_id   string `xml:"prepay_id"`
	Trade_type  string `xml:"trade_type"`
	Mweb_url    string `xml:"mweb_url"`
	Code_url    string `xml:"code_url"`
}

type WXPayNotifyReq struct {
	Return_code          string `xml:"return_code"`
	Return_msg           string `xml:"return_msg"`
	Appid                string `xml:"appid"`
	Mch_id               string `xml:"mch_id"`
	Device_info          string `xml:"device_info"`
	Nonce                string `xml:"nonce_str"`
	Sign                 string `xml:"sign"`
	Sign_type            string `xml:"sign_type"`
	Result_code          string `xml:"result_code"`
	Openid               string `xml:"openid"`
	Is_subscribe         string `xml:"is_subscribe"`
	Trade_type           string `xml:"trade_type"`
	Bank_type            string `xml:"bank_type"`
	Total_fee            int    `xml:"total_fee"`
	Settlement_total_fee int    `xml:"settlement_total_fee"`
	Fee_type             string `xml:"fee_type"`
	Cash_fee             int    `xml:"cash_fee"`
	Cash_fee_Type        string `xml:"cash_fee_type"`
	Coupon_fee           string `xml:"coupon_fee"`
	Coupon_count         string `xml:"coupon_count"`
	Coupon_type_0        string `xml:"coupon_type_0"`
	Coupon_id_0          string `xml:"coupon_id_0"`
	Coupon_fee_0         string `xml:"coupon_fee_0"`
	Transaction_id       string `xml:"transaction_id"`
	Out_trade_no         string `xml:"out_trade_no"`
	Attach               string `xml:"attach"`
	Time_end             string `xml:"time_end"`
}

type WXPayNotifyResp struct {
	Return_code string `xml:"return_code"`
	Return_msg  string `xml:"return_msg"`
}
type Wxpay_GZH_Callback struct {
	BaseController
}

func (c *Wxpay_GZH_Callback) CallBack() {
	uri := c.Ctx.Request.RequestURI
	var style int
	var t int
	switch uri {
	case "/mobile/wx_gzh_pay_callback": //支付订单
		style = 0
		t = 0
	case "/mobile/wx_gzh_recharge_callback": //支付订单
		style = 0
		t = 1
	}
	c.EnableRender = false
	WxpayCallback(c.Ctx.ResponseWriter, c.Ctx.Request, style, t)
}

type Wxpay_Web_Callback struct {
	BaseController
}

func (c *Wxpay_Web_Callback) CallBack() {
	uri := c.Ctx.Request.RequestURI
	var style int
	var t int
	switch uri {
	case "/mobile/wx_web_pay_callback": //支付订单
		style = 3
		t = 0
	case "/mobile/wx_web_recharge_callback": //支付订单
		style = 3
		t = 1
	}
	c.EnableRender = false
	WxpayCallback(c.Ctx.ResponseWriter, c.Ctx.Request, style, t)
}

type Wxpay_Xapp_Callback struct {
	BaseController
}

func (c *Wxpay_Xapp_Callback) CallBack() {
	uri := c.Ctx.Request.RequestURI
	var t int
	switch uri {
	case "/mobile/wx_xapp_pay_callback": //支付订单
		t = 0
	case "/mobile/wx_xapp_recharge_callback": //支付订单
		t = 1
	}
	c.EnableRender = false
	WxpayCallback(c.Ctx.ResponseWriter, c.Ctx.Request, 2, t)
}

type Wxpay_H5_Callback struct {
	BaseController
}

func (c *Wxpay_H5_Callback) CallBack() {
	uri := c.Ctx.Request.RequestURI
	var style int
	var t int
	switch uri {
	case "/mobile/wx_h5_pay_callback": //支付订单
		style = 1
		t = 0
	case "/mobile/wx_h5_recharge_callback": //支付订单
		style = 1
		t = 1
	}
	c.EnableRender = false
	WxpayCallback(c.Ctx.ResponseWriter, c.Ctx.Request, style, t)
}

type Wxpay_App_Callback struct {
	BaseController
}

func (c *Wxpay_App_Callback) CallBack() {
	uri := c.Ctx.Request.RequestURI
	var style int
	var t int
	switch uri {
	case "/mobile/wx_app_pay_callback": //支付订单
		style = 4
		t = 0
	case "/mobile/wx_app_recharge_callback": //支付订单
		style = 4
		t = 1
	}
	c.EnableRender = false
	WxpayCallback(c.Ctx.ResponseWriter, c.Ctx.Request, style, t)
}

func WxPay(uid, title, ip, oid string, money float64, style, t int) map[string]interface{} {
	beego.Debug("微信支付")
	var js = make(map[string]interface{})
	if member := models.Query("select * from mt_member where id=" + uid); member != nil {
		//请求UnifiedOrder的代码
		var yourReq UnifyOrderReq
		var appid string
		mch_id := models.WxPay_mchid
		wechatkey := models.WxPay_secret
		yourReq.Product_id = ""
		var openid string
		var url string
		var m = make(map[string]interface{})
		switch style {
		case 0: //公众号支付
			appid = models.AppID
			openid = member[0]["wx_openid_gzh"].(string)
			if t == 0 {
				url = "/mobile/wx_gzh_pay_callback"
			} else if t == 1 {
				url = "/mobile/wx_gzh_recharge_callback"
			}
			yourReq.Trade_type = "JSAPI"

		case 1: //h5支付
			appid = models.AppID
			if t == 0 {
				url = "/mobile/wx_h5_pay_callback"
			} else if t == 1 {
				url = "/mobile/wx_h5_recharge_callback"
			}
			yourReq.Trade_type = "MWEB"
			var scene = map[string]map[string]interface{}{"h5_info": {"type": "Wap", "wap_url": models.Urlc, "wap_name": "统采科技"}}
			jsonres, err := json.Marshal(&scene)
			if err != nil {
				beego.Debug(err)
				js["error"] = err
			}
			yourReq.Scene_info = string(jsonres)
			m["scene_info"] = yourReq.Scene_info
			yourReq.Openid = openid
		case 2: //小程序支付
			appid = models.XappAppid
			openid = member[0]["wx_openid_xapp"].(string)
			if t == 0 {
				url = "/mobile/wx_xapp_pay_callback"
			} else if t == 1 {
				url = "/mobile/wx_xapp_recharge_callback"
			}
			yourReq.Trade_type = "JSAPI"
		case 3: //电脑网站扫码支付
			appid = models.AppID
			// mch_id = "1502775991"
			if t == 0 {
				url = "/mobile/wx_web_pay_callback"
			} else if t == 1 {
				oid = uid
				url = "/mobile/wx_web_recharge_callback"
			}
			yourReq.Trade_type = "NATIVE"
			m["product_id"] = oid
			yourReq.Product_id = oid
		case 4: //app支付
			appid = `wx9e0757117653ccbd`
			wechatkey = "0qlC12ha5Teb0oaQMaySBmJz3UMtzfbR"
			mch_id = `1508389251`
			title = "统采商城-" + title
			if t == 0 {
				url = "/mobile/wx_app_pay_callback"
			} else if t == 1 {
				oid = uid
				url = "/mobile/wx_app_recharge_callback"
			}
			yourReq.Trade_type = "APP"
		}

		yourReq.Appid = appid
		yourReq.Mch_id = mch_id
		yourReq.Body = title //浏览器打开的移动网页的主页title名-商品概述
		yourReq.Attach = oid
		yourReq.Nonce_str = sword.RandStr(32)
		yourReq.Notify_url = models.Urlc + url
		yourReq.Spbill_create_ip = ip
		yourReq.Openid = openid
		if uid == "1316" {
			yourReq.Total_fee = 1
		} else {
			yourReq.Total_fee = int(money * 100) // 单位是分 单位换为真实大小 注意要把元转换为分
		}
		//yourReq.Total_fee = money * 100 // 单位是分 单位换为真实大小 注意要把元转换为分
		// yourReq.Total_fee = 10
		yourReq.Out_trade_no = sword.RandStr(32) //订单号

		m["appid"] = yourReq.Appid
		m["body"] = yourReq.Body
		m["mch_id"] = yourReq.Mch_id
		m["notify_url"] = yourReq.Notify_url
		m["trade_type"] = yourReq.Trade_type
		m["spbill_create_ip"] = yourReq.Spbill_create_ip
		m["total_fee"] = yourReq.Total_fee
		m["out_trade_no"] = yourReq.Out_trade_no
		m["nonce_str"] = yourReq.Nonce_str
		if yourReq.Openid != "" {
			m["openid"] = yourReq.Openid
		}
		m["attach"] = yourReq.Attach
		// utils.Display("m", m)
		yourReq.Sign = wxpayCalcSign(m, wechatkey) //这个key 微信商户平台(pay.weixin.qq.com)-->账户中心-->账户设置-->API安全
		bytes_req, err := xml.Marshal(yourReq)
		if err != nil {
			beego.Debug("转换为xml错误:", err)
			js["error"] = err
		}
		str_req := strings.Replace(string(bytes_req), "UnifyOrderReq", "xml", -1) //fmt.Println("转换为xml--------", str_req)

		bytes_req = []byte(str_req) //发送unified order请求
		req, err := http.NewRequest("POST", "https://api.mch.weixin.qq.com/pay/unifiedorder", bytes.NewReader(bytes_req))
		if err != nil {
			beego.Debug("New Http Request发生错误，原因:", err)
			js["error"] = err
			return js
		}
		req.Header.Set("Accept", "application/xml")
		//这里的http header的设置是必须设置的.
		req.Header.Set("Content-Type", "application/xml;charset=utf-8")
		client := http.Client{}
		resp, _err := client.Do(req)
		if _err != nil {
			beego.Debug("请求微信支付统一下单接口发送错误, 原因:", _err)
			js["error"] = _err
			return js
		}
		//------------------到这里统一下单接口就已经执行完成了-------------------
		respBytes, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			beego.Debug("解析返回body错误", err)
			js["error"] = err
			return js
		}
		xmlResp := UnifyOrderResp{}
		_err = xml.Unmarshal(respBytes, &xmlResp)
		//处理return code.
		if xmlResp.Return_code == "FAIL" {
			beego.Debug("微信支付统一下单不成功，原因:", xmlResp.Return_msg, " str_req-->", str_req)
			js["error"] = xmlResp.Return_msg
			return js
		}
		//这里已经得到微信支付的prepay id，需要返给客户端页面，由客户端继续完成支付流程
		//向数据库存入 WxBill 订单号yourReq.Out_trade_no user的wx_id orderId 时间 total_fee
		if style == 0 || style == 2 {
			timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
			js["package"] = "prepay_id=" + xmlResp.Prepay_id
			js["appId"] = yourReq.Appid
			js["timeStamp"] = timeStamp
			js["nonceStr"] = yourReq.Nonce_str
			paySign := getPaySign(&yourReq, &xmlResp, timeStamp, wechatkey)
			js["paySign"] = paySign
		} else if style == 1 {
			js["url"] = xmlResp.Mweb_url
		} else if style == 3 {
			js["url"] = xmlResp.Code_url
		} else if style == 4 {
			timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
			js["appId"] = xmlResp.Appid
			js["partnerId"] = "1508389251"
			js["package"] = xmlResp.Prepay_id
			js["nonceStr"] = xmlResp.Nonce_str
			js["timeStamp"] = timeStamp
			paySign := getPaySignApp(&yourReq, &xmlResp, timeStamp, wechatkey)
			js["paySign"] = paySign
		}
		beego.Debug("微信结束")
		return js
	} else {
		js["error"] = "用户不存在"
		return js
	}
}
func WxpayCallback(w http.ResponseWriter, r *http.Request, style, t int) {
	// body
	body, err := ioutil.ReadAll(r.Body)
	beego.Debug("开始微信回调")
	if err != nil {
		beego.Debug("读取http body失败，原因!", err)
		http.Error(w.(http.ResponseWriter), http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
		return
	}
	defer r.Body.Close()
	var mr WXPayNotifyReq
	err = xml.Unmarshal(body, &mr)
	if err != nil {
		beego.Debug("解析HTTP Body格式到xml失败，原因!", err)
		http.Error(w.(http.ResponseWriter), http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
		return
	}
	// utils.Display("res", mr)
	var reqMap map[string]interface{}
	reqMap = make(map[string]interface{}, 0)

	reqMap["return_code"] = mr.Return_code
	reqMap["return_msg"] = mr.Return_msg
	reqMap["appid"] = mr.Appid
	reqMap["mch_id"] = mr.Mch_id
	reqMap["device_info"] = mr.Device_info
	reqMap["nonce_str"] = mr.Nonce
	reqMap["sign_type"] = mr.Sign_type
	reqMap["result_code"] = mr.Result_code
	reqMap["openid"] = mr.Openid
	reqMap["is_subscribe"] = mr.Is_subscribe
	reqMap["trade_type"] = mr.Trade_type
	reqMap["bank_type"] = mr.Bank_type
	reqMap["total_fee"] = mr.Total_fee
	reqMap["settlement_total_fee"] = mr.Settlement_total_fee
	reqMap["fee_type"] = mr.Fee_type
	reqMap["cash_fee"] = mr.Cash_fee
	reqMap["cash_fee_type"] = mr.Cash_fee_Type
	reqMap["coupon_fee"] = mr.Coupon_fee
	reqMap["coupon_count"] = mr.Coupon_count
	reqMap["coupon_type_0"] = mr.Coupon_type_0
	reqMap["coupon_id_0"] = mr.Coupon_id_0
	reqMap["coupon_fee_0"] = mr.Coupon_fee_0
	reqMap["transaction_id"] = mr.Transaction_id
	reqMap["out_trade_no"] = mr.Out_trade_no
	reqMap["attach"] = mr.Attach
	reqMap["time_end"] = mr.Time_end

	var resp WXPayNotifyResp
	//进行签名校验
	beego.Debug(wxpayVerifySign(reqMap, mr.Sign))
	if wxpayVerifySign(reqMap, mr.Sign) {
		//这里就可以更新我们的后台数据库了，其他业务逻辑同理。
		resp.Return_code = "SUCCESS"
		resp.Return_msg = "OK"
		bytes, _err := xml.Marshal(resp)
		strResp := strings.Replace(string(bytes), "WXPayNotifyResp", "xml", -1)
		if _err != nil {
			beego.Debug("xml编码失败，原因：", _err)
			http.Error(w.(http.ResponseWriter), http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
			return
		}

		//支付成功逻辑
		go func() {
			nowtime := sword.Gettimes("")
			var mem orm.Params
			if style == 0 || style == 1 {
				mem = models.Query(`select id from mt_member where wx_openid_gzh='` + mr.Openid + `'`)[0]
			} else if style == 2 {
				mem = models.Query(`select id from mt_member where wx_openid_xapp='` + mr.Openid + `'`)[0]
			} else if style == 3 || style == 4 {
				if t == 0 {
					mem = models.Query(`select a.uid as id from mt_order a where a.id in(` + mr.Attach + `)`)[0]
				} else {
					mem = models.Query(`select id from mt_member where id=` + mr.Attach)[0]
				}
			}
			uid := mem["id"].(string)
			beego.Debug(t)
			if t == 0 {
				oid := mr.Attach
				order := models.Query(`select id,money from mt_order where id in(` + oid + `)`)
				integralbf, err := strconv.ParseFloat(fmt.Sprint(models.Systems()["integral"]), 64)
				if err != nil {
					beego.Debug(err)
					integralbf = 100
				}
				o := models.Orm()
				o.Begin()
				if _, err := o.Raw(`update mt_order set status=2,paytime='` + nowtime + `',paytype=2 where id in(` + mr.Attach + `)`).Exec(); err != nil {
					beego.Debug(err)
					o.Rollback()
					return
				}
				for _, v := range order {
					money := fmt.Sprint(v["money"])
					if _, err = o.Raw(fmt.Sprintf(`insert into mt_member_money_detail (uid,type,money,oid,addtime,return_code,transaction_id,time_end,bank_type,trade_type,
						nonce_str,sign,appid,openid,fee_type,total_fee,paytype,mch_id) value ('%v','%v','%v','%v','%v','%v','%v','%v','%v','%v','%v','%v','%v','%v',
						'%v','%v','%v','%v')`, uid, 3, money, v["id"], nowtime, mr.Return_code, mr.Transaction_id, mr.Time_end, mr.Bank_type, mr.Trade_type,
						mr.Nonce, mr.Sign, mr.Appid, mr.Openid, mr.Fee_type, mr.Total_fee, 2, mr.Mch_id)).Exec(); err != nil {
						beego.Debug(err)
						o.Rollback()
						return
					}
					moneyf, _ := strconv.ParseFloat(money, 64)
					integral := moneyf / integralbf
					if _, err := o.Raw(fmt.Sprintf(`update mt_member set integral=integral+%.f where id=%v`, integral, uid)).Exec(); err != nil {
						beego.Debug(err)
						o.Rollback()
						return
					}
					if _, err := o.Raw(fmt.Sprintf(`insert into mt_member_integral (uid,type,number,oid,addtime) values 
								('%v','%v','%.f','%v','%v')`, uid, 0, integral, v["id"], nowtime)).Exec(); err != nil {
						beego.Debug(err)
						o.Rollback()
						return
					}
				}
				o.Commit()
				beego.Debug(mr.Attach)
				PayPush(mr.Attach)
			} else if t == 1 {
				var moneyf = float64(mr.Total_fee) / 100
				beego.Debug(moneyf)
				o := models.Orm()
				o.Begin()
				if _, err := o.Raw(fmt.Sprintf(`update mt_member set money=money+%.2f where id=%v`, moneyf, uid)).Exec(); err != nil {
					beego.Debug(err)
					o.Rollback()
					return
				}
				if _, err := o.Raw(fmt.Sprintf(`insert into mt_member_money_detail (uid,type,money,oid,addtime,return_code,transaction_id,time_end,bank_type,trade_type,
					nonce_str,sign,appid,openid,fee_type,total_fee,paytype,mch_id) value ('%v','%v','%.2f','%v','%v','%v','%v','%v','%v','%v','%v','%v','%v','%v',
					'%v','%v','%v','%v')`, uid, 0, moneyf, "", nowtime, mr.Return_code, mr.Transaction_id, mr.Time_end, mr.Bank_type, mr.Trade_type,
					mr.Nonce, mr.Sign, mr.Appid, mr.Openid, mr.Fee_type, mr.Total_fee, 2, mr.Mch_id)).Exec(); err != nil {
					beego.Debug(err)
					o.Rollback()
					return
				}
				o.Commit()
				member := models.Query(`select monicker,mobile from mt_member where id = ?`, uid)[0]
				now := time.Now().Local().Format("2006-1-2 15:04:05")
				template := map[string]map[string]interface{}{
					"first":    {"value": `有新的充值记录,请及时处理`},
					"keyword1": {"value": fmt.Sprint(member["monicker"]), "color": `#36353A`},
					"keyword2": {"value": fmt.Sprint(member["mobile"]), "color": `#36353A`},
					"keyword3": {"value": now, "color": `#9A9A9A`},
					"keyword4": {"value": `充值` + strconv.FormatFloat(moneyf, 'f', -1, 64) + `元`, "color": `#e31939`},
				}
				models.Push(`ozAyh0t31zHP9-ueakhHrwpqUfVE`, `DLRBKSoslNWa6QcuZ7GdZN4YAM3L6Lpq_Y9D-IgnSCQ`, template, "", "")

			}
		}()
		w.(http.ResponseWriter).WriteHeader(http.StatusOK)
		beego.Debug(strResp)
		fmt.Fprint(w.(http.ResponseWriter), strResp)
	} else {
		resp.Return_code = "FAIL"
		resp.Return_msg = "failed to verify sign, please retry!"
		bytes, _err := xml.Marshal(resp)
		strResp := strings.Replace(string(bytes), "WXPayNotifyResp", "xml", -1)
		if _err != nil {
			beego.Debug("xml编码失败，原因：", _err)
			http.Error(w.(http.ResponseWriter), http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
			return
		}
		w.(http.ResponseWriter).WriteHeader(http.StatusOK)
		fmt.Fprint(w.(http.ResponseWriter), strResp)
	}

	//结果返回，微信要求如果成功需要返回return_code "SUCCESS"
}

func wxpayCalcSign(mReq map[string]interface{}, key string) string {

	//fmt.Println("========STEP 1, 对key进行升序排序.========")
	//fmt.Println("微信支付签名计算, API KEY:", key)
	//STEP 1, 对key进行升序排序.
	sorted_keys := make([]string, 0)
	for k, _ := range mReq {
		sorted_keys = append(sorted_keys, k)
	}

	sort.Strings(sorted_keys)

	//fmt.Println("========STEP2, 对key=value的键值对用&连接起来，略过空值========")
	//STEP2, 对key=value的键值对用&连接起来，略过空值
	var signStrings string
	for _, k := range sorted_keys {
		//fmt.Printf("k=%v, v=%v\n", k, mReq[k])
		value := fmt.Sprintf("%v", mReq[k])
		if value != "" && value != "0" {
			signStrings = signStrings + k + "=" + value + "&"
		}
	}
	//fmt.Println("========STEP3, 在键值对的最后加上key=API_KEY========")
	//STEP3, 在键值对的最后加上key=API_KEY
	if key != "" {
		signStrings = signStrings + "key=" + key
	}

	//fmt.Println("========STEP4, 进行MD5签名并且将所有字符转为大写.========")
	//STEP4, 进行MD5签名并且将所有字符转为大写.
	md5Ctx := md5.New()
	md5Ctx.Write([]byte(signStrings))
	cipherStr := md5Ctx.Sum(nil)
	upperSign := strings.ToUpper(hex.EncodeToString(cipherStr))

	return upperSign
}
func wxpayVerifySign(needVerifyM map[string]interface{}, sign string) bool {
	signCalc := wxpayCalcSign(needVerifyM, models.WxPay_secret)

	if sign == signCalc {
		return true
	}
	beego.Debug("签名校验失败!")
	return false
}

func getPaySign(yourReq *UnifyOrderReq, xmlResp *UnifyOrderResp, timeStamp, wechatkey string) string {
	p := make(map[string]interface{}, 0)
	p["appId"] = yourReq.Appid
	//p["timeStamp"] = yourReq.Out_trade_no
	p["timeStamp"] = timeStamp
	p["nonceStr"] = yourReq.Nonce_str
	p["package"] = "prepay_id=" + xmlResp.Prepay_id
	p["signType"] = "MD5"

	return wxpaySign(p, wechatkey)
}

func getPaySignApp(yourReq *UnifyOrderReq, xmlResp *UnifyOrderResp, timeStamp, wechatkey string) string {
	p := make(map[string]interface{}, 0)
	p["appid"] = xmlResp.Appid
	p["partnerid"] = "1508389251"
	p["prepayid"] = xmlResp.Prepay_id
	p["timestamp"] = timeStamp
	p["noncestr"] = xmlResp.Nonce_str
	p["package"] = "Sign=WXPay"
	return wxpaySign(p, wechatkey)
}

func wxpaySign(mReq map[string]interface{}, key string) string {

	//STEP 1, 对key进行升序排序.
	sorted_keys := make([]string, 0)
	for k, _ := range mReq {
		sorted_keys = append(sorted_keys, k)
	}

	sort.Strings(sorted_keys)

	//STEP2, 对key=value的键值对用&连接起来，略过空值
	var signStrings string
	for i, k := range sorted_keys {
		//fmt.Printf("k=%v, v=%v\n", k, mReq[k])
		value := fmt.Sprintf("%v", mReq[k])
		if value != "" {
			if i != (len(sorted_keys) - 1) {
				signStrings = signStrings + k + "=" + value + "&"
			} else {
				signStrings = signStrings + k + "=" + value //最后一个不加此符号
			}
		}
	}
	//fmt.Println("=====键值对==============", signStrings)

	//STEP3, 在键值对的最后加上key=API_KEY
	if key != "" {
		signStrings = signStrings + "&key=" + key
	}

	//STEP4, 进行MD5签名并且将所有字符转为大写.
	//md5Ctx := md5.New()
	//md5Ctx.Write([]byte(signStrings))
	//upperSign := strings.ToUpper(hex.EncodeToString(md5Ctx.Sum(nil)))

	md5Ctx := md5.New()
	md5Ctx.Write([]byte(signStrings))
	cipherStr := md5Ctx.Sum(nil)
	upperSign := strings.ToUpper(hex.EncodeToString(cipherStr))
	return upperSign
}

func getTicketSigNature(uri string, yourReq *UnifyOrderReq) string {

	//urlstr := beego.AppConfig.String("baseURL") + uri
	urlstr := models.Urlc + uri
	n := make(map[string]interface{}, 0)
	n["noncestr"] = yourReq.Nonce_str
	n["jsapi_ticket"] = 0
	n["timestamp"] = yourReq.Out_trade_no
	n["url"] = urlstr
	signature := wxJsTicketSign(n)
	return signature
}

// 微信支付页面config签名
func wxJsTicketSign(mReq map[string]interface{}) string {

	//fmt.Println("========STEP 1, 对key进行升序排序.========")
	//fmt.Println("微信支付签名计算, API KEY:", key)
	//STEP 1, 对key进行升序排序.
	sorted_keys := make([]string, 0)
	for k, _ := range mReq {
		sorted_keys = append(sorted_keys, k)
	}

	sort.Strings(sorted_keys)

	//fmt.Println("========STEP2, 对key=value的键值对用&连接起来，略过空值========")
	//STEP2, 对key=value的键值对用&连接起来，略过空值
	var signStrings string
	for i, k := range sorted_keys {
		//fmt.Printf("k=%v, v=%v\n", k, mReq[k])
		value := fmt.Sprintf("%v", mReq[k])
		if value != "" {
			if i != (len(sorted_keys) - 1) {
				signStrings = signStrings + k + "=" + value + "&"
			} else {
				signStrings = signStrings + k + "=" + value //最后一个不加此符号
			}
		}
	}

	//对字符串进行SHA1哈希
	t := sha1.New()
	io.WriteString(t, signStrings)
	upperSign := fmt.Sprintf("%x", t.Sum(nil))
	return upperSign
}

var (
	Alipay_appId     = "2018050402632194"
	Alipay_partnerId = "2088821151805562"
	// RSA2(SHA256)
	Alipay_aliPublicKey = []byte(`-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmYxf7o2R7oHRr/WoJy5H
KH9Fh+rDv0PDPP0p1l31ZWikGn9/OGWmMv18Hzw3s3+dnFYSAAq8FiBwnzo8RuPk
0Ix/T+cmN6BFkl7NUwM8LaTzodGfXgTGNXyfR55kveki+FJ/27dXdz1fFjVyojUX
5ht3cJ0eoUYSAV8W2E5o8t8w7esE+iyjlTwkfLcmQrkkilw/Nnmy5/Icx78x1yCi
SuMhwcqVQ9YK8ig/LjVw98Neodn+CX/1DaEFKlAXQ9savPhmOSGAWDmze5XoGE1+
83qtoa6OkxO0jzzgn4PltZ8s3KqxszONAwnvSsuBMAmkYQ75Xdh8dHORL2fNiO9f
3wIDAQAB
-----END PUBLIC KEY-----
`)

	Alipay_publicKey = []byte(`-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAn6AP5wafG2/rP92E9GDY
0v8K7J6hCb85UXNaEtsDUxBEQ5JAk6F1EBrjNoHi+QlRntUk5uis+jtcOAzBSq6f
EyZyZtsZuyz0/8Ayr9GD0GaRYtq2fD1Pn9/W0Pipd/UElBs629O5XrQL58vXjNEn
xYxDnISEDgUEN1mfcPORHLMXTwVsXMuAF2xbW/CskF5Gsi9v2a+3PP7x6qyxPEnf
Xe4avfEZ0Bl4XySWoWFlrgAYIOMR6OhnNkBvUCzVXU10R66ZrOEhxXQEkzef78WL
XgjgodHop1iDWEy4gVHk1ZA6XPOqB228Lztagmcc6eNtZvYOfMF0f6JkI44LPvmO
zQIDAQAB
-----END PUBLIC KEY-----
`)

	Alipay_privateKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAn6AP5wafG2/rP92E9GDY0v8K7J6hCb85UXNaEtsDUxBEQ5JA
k6F1EBrjNoHi+QlRntUk5uis+jtcOAzBSq6fEyZyZtsZuyz0/8Ayr9GD0GaRYtq2
fD1Pn9/W0Pipd/UElBs629O5XrQL58vXjNEnxYxDnISEDgUEN1mfcPORHLMXTwVs
XMuAF2xbW/CskF5Gsi9v2a+3PP7x6qyxPEnfXe4avfEZ0Bl4XySWoWFlrgAYIOMR
6OhnNkBvUCzVXU10R66ZrOEhxXQEkzef78WLXgjgodHop1iDWEy4gVHk1ZA6XPOq
B228Lztagmcc6eNtZvYOfMF0f6JkI44LPvmOzQIDAQABAoIBAGJpl4RSw8Nxs/Mz
CqZ0Exm63ixV/Gj6+UarPIxFdP5AGCYkxCWAtKCSQyU23Q223hhzxoWKTCMWd9ui
mYUGtdJjsMKTMIECzaXkBBv7qy3QHrB4sWtVjYK+yT0bIbhwWjtJsncXSMEHdhOZ
zDHoPYIA4SpdVOEj3J6XZcKImB29nyQDXxP2KGNYpQXbTcEf8a0CbNcyW/RvtyVR
hNNPAnCZvSxpKR+fgxMeS1bdzG9VR9dFcqm/5WCe6jrQKTccMVOpZ+jncBcwnVhl
SsEF6rNURCQgg74bmORR5gxNMiNv4mPf/s6ZSqJVOndenAZQlEWciTELKbj34IJq
BTjW2q0CgYEA0Yqk89+qm6dvPbifML5doj7EdhJNaCTIps0H7SdNJmRvyrgZ8qji
HRp2QDjkVxrJwIxUSmphx3MijD7uLz23gpu2RzAW6gYc+hx0NX0LaWP2GSKyIXIx
H3lOT0wxxOOAlJJ35XWAx+/AsazT3w5A+/VZIj15wF7Ndgoa3RjhADsCgYEAwwQ4
TqAu6U54zUiWPIdf29oQeBLf2LXk+1Wl+AY9BtT8MDdFR3/DFTpRzk6Hl29Vi4l/
9cud8G7q9DufbClLxhg+upifAD9ryzGt9jCNHKc2nKNuRHniDPM4GlZs18HYXLIe
o6OLg3qC2ME+MWoxlDUYGw2CftYqkzdVMEwshJcCgYEAre4Wc7PBishVZvcbdDtf
v2+4ZYVVqU93GjVwEeMgf/C4dp2QNEMIxT2U0EQpDUBYHTKeONLK7OJd1+nYjW/+
JjSX/ckmDAUdAmKh91AfK9DkkwKgt3Bw4/4uCVZmrVZmAWz+hoGdbthMq26Ywzqy
qDGEVg6PRCWtCADlQYcIJMcCgYBym6FHu+W14RMneZgpXFmeh+oT1uvMnSFD/9K5
D1mAEV1gLKs/WLtaV1rKRuZyvdBlX9peplpceaMFA6EuXJqWgZsj6BvRdnQwBzM4
MtJLW43Bwl5ESejqOWnoOJBgwCAaYeeVvcB49V++aNrXCZS3h/hxtZ/SUKTWvbcH
2kxzYwKBgQCKWP7tFrdcZkLXIjPXbP56XkMoXHBCs00qVFyh5ntALXUWyz+BfXDy
Q8G6NkJ1zPuMG8+YPY2m25VgpktX4Hc/ROOmh1Ss1s6wDuRWRYfZgmFkCmBu5ogN
snzPrk5VpPM2RU0f5Hn35F40MCiBdrT+dpY7/lVYhrKJvKTPwa1jbw==
-----END RSA PRIVATE KEY-----

		`)
)

type Alipay_Callback struct {
	BaseController
}

func (c *Alipay_Callback) CallBack() {
	c.EnableRender = false
	//var client = alipay.New(Alipay_appId, Alipay_partnerId, Alipay_aliPublicKey, Alipay_privateKey, true)
	var client = alipay.New(Alipay_appId, string(Alipay_aliPublicKey), string(Alipay_privateKey), true)
	var noti, err = client.GetTradeNotification(c.Ctx.Request)
	beego.Debug("进入微信支付回调")
	if noti != nil {
		params := noti.PassbackParams
		money := noti.BuyerPayAmount
		if money == "" {
			return
		}
		paramsp, err := url.ParseQuery(params)
		if err != nil {
			beego.Debug(err)
			return
		}
		uid := paramsp.Get("uid")
		mid := paramsp.Get("mid")
		oid := paramsp.Get("oid")
		if uid == "" {
			params, err = url.QueryUnescape(params)

			if err != nil {
				beego.Debug(err)
				return
			}
			paramsp, err = url.ParseQuery(params)
			if err != nil {
				beego.Debug(err)
				return
			}
			uid = paramsp.Get("uid")
			mid = paramsp.Get("mid")
			oid = paramsp.Get("oid")
		}

		if mid != "0" && mid != "" {
			if istrue := models.Query(`select id from mt_member_money_detail where id=` + mid + ` and uid=` + uid + ` and appid=` + Alipay_appId + `
			 and money=` + money + ` and ispay=0`); istrue == nil {
				beego.Debug("资金数据错误")
				return
			}
			o := models.Orm()
			o.Begin()
			if _, err := o.Raw(`update mt_member_money_detail set ispay=1 where uid=` + uid).Exec(); err != nil {
				beego.Debug(err)
				o.Rollback()
				return
			}
			if _, err := o.Raw(`update mt_member set money=money+` + money + ` where id=` + uid).Exec(); err != nil {
				beego.Debug(err)
				o.Rollback()
				return
			}
			o.Commit()
			member := models.Query(`select monicker,mobile from mt_member where id = ?`, uid)[0]
			now := time.Now().Local().Format("2006-1-2 15:04:05")
			template := map[string]map[string]interface{}{
				"first":    {"value": `有新的充值记录,请及时处理`},
				"keyword1": {"value": fmt.Sprint(member["monicker"]), "color": `#36353A`},
				"keyword2": {"value": fmt.Sprint(member["mobile"]), "color": `#36353A`},
				"keyword3": {"value": now, "color": `#9A9A9A`},
				"keyword4": {"value": `充值` + money + `元`, "color": `#e31939`},
			}
			models.Push(`ozAyh0t31zHP9-ueakhHrwpqUfVE`, `DLRBKSoslNWa6QcuZ7GdZN4YAM3L6Lpq_Y9D-IgnSCQ`, template, "", "")
			fmt.Fprint(c.Ctx.ResponseWriter, "success")
		} else {
			nowtime := sword.Gettimes("")
			if oid == "" {
				return
			}
			// moneys := models.Query(`select sum(money) as moneys from mt_order where id in(` + oid + `)`)[0]["moneys"]
			// if money != moneys {
			// 	beego.Debug("订单金额错误")
			// 	return
			// }
			order := models.Query(`select id,money from mt_order where id in(` + oid + `)`)
			integralbf, err := strconv.ParseFloat(fmt.Sprint(models.Systems()["integral"]), 64)
			if err != nil {
				beego.Debug(err)
				integralbf = 100
			}
			o := models.Orm()
			o.Begin()
			if _, err := o.Raw(`update mt_order set status=2,paytime='` + nowtime + `',paytype=3 where id in(` + oid + `)`).Exec(); err != nil {
				o.Rollback()
				beego.Debug(err)
				return
			}
			for _, v := range order {
				money := fmt.Sprint(v["money"])
				if _, err = o.Raw(fmt.Sprintf(`insert into mt_member_money_detail (uid,type,money,oid,addtime,appid,paytype,outtradeno,buyerpay) value 
						('%v','%v','%v','%v','%v','%v','%v','%v','%v')`, uid, 3, money, v["id"], nowtime, Alipay_appId, 3, noti.OutTradeNo, noti.BuyerPayAmount)).Exec(); err != nil {
					beego.Debug(err)
					o.Rollback()
					return
				}
				moneyf, _ := strconv.ParseFloat(money, 64)
				integral := moneyf / integralbf
				if _, err := o.Raw(fmt.Sprintf(`update mt_member set integral=integral+%.f where id=%v`, integral, uid)).Exec(); err != nil {
					beego.Debug(err)
					o.Rollback()
					return
				}
				if _, err := o.Raw(fmt.Sprintf(`insert into mt_member_integral (uid,type,number,oid,addtime) values 
							('%v','%v','%.f','%v','%v')`, uid, 0, integral, v["id"], nowtime)).Exec(); err != nil {
					beego.Debug(err)
					o.Rollback()
					return
				}
			}
			o.Commit()
			PayPush(oid)
			fmt.Fprint(c.Ctx.ResponseWriter, "success")
		}
	} else {
		beego.Debug(err)
	}
}

func Alipay(uid string, money float64, oid string, t int, style int) (string, error) {
	var client = alipay.New(Alipay_appId, string(Alipay_publicKey), string(Alipay_privateKey), true)
	//var client = alipay.New(Alipay_appId, Alipay_partnerId, Alipay_publicKey, Alipay_privateKey, true)

	var notify_url = models.Urlc + "/mobile/alipay_callback"
	var out_trade_no = sword.RandomStr(32)
	var total_amount = fmt.Sprintf(`%.2f`, money)
	// total_amount = "0.01"
	var returnurl string
	var subject string
	var mid int64
	if t == 0 {
		returnurl = models.Urlc + "/mobile/my/order"
		if style == 3 {
			returnurl = models.Urlc + "/my/order"
		}
		subject = "支付订单"
	} else {
		subject = "充值"
		sql := fmt.Sprintf(`insert into mt_member_money_detail (uid,type,money,addtime,appid,paytype,outtradeno,buyerpay,ispay) 
		value ('%v','%v','%v','%v','%v','%v','%v','%v','%v')`, uid, 0, total_amount, sword.Gettimes(""), Alipay_appId, 3, out_trade_no,
			total_amount, 0)
		if res, err := models.Orm().Raw(sql).Exec(); err != nil {
			return "", err
		} else {
			mid, _ = res.LastInsertId()
		}
	}

	if uid == "" {
		return "", errors.New("缺少用户id")
	}
	param := `uid=` + uid + `&oid=` + oid + `&mid=` + fmt.Sprint(mid)
	encodepa := url.QueryEscape(param)
	switch style {
	case 1, 0: //手机网站
		var p = alipay.AliPayTradeWapPay{}
		p.NotifyURL = notify_url
		p.OutTradeNo = out_trade_no
		p.TotalAmount = total_amount
		p.PassbackParams = encodepa
		if returnurl != "" {
			p.ReturnURL = returnurl
		}
		p.Subject = subject
		html, err := client.TradeWapPay(p)
		if err != nil {
			beego.Debug(err)
			return "", err
		} else {
			return html.String(), err
		}
	case 3: //电脑网站扫码支付
		var p = alipay.AliPayTradePagePay{}
		p.NotifyURL = notify_url
		p.OutTradeNo = out_trade_no
		p.TotalAmount = total_amount
		p.PassbackParams = encodepa
		p.ProductCode = "FAST_INSTANT_TRADE_PAY"
		if returnurl != "" {
			p.ReturnURL = returnurl
		}
		p.Subject = subject

		html, err := client.TradePagePay(p)
		if err != nil {
			return "", err
		} else {
			return html.String(), err
		}
	case 4:
		var p = alipay.AliPayTradeAppPay{}
		p.Subject = subject
		p.OutTradeNo = out_trade_no
		p.TotalAmount = total_amount
		p.PassbackParams = encodepa
		p.ProductCode = "QUICK_MSECURITY_PAY"
		p.NotifyURL = notify_url
		html, err := client.TradeAppPay(p)
		if err != nil {
			return "", err
		} else {
			return html, err
		}
	}
	return "", errors.New("未知错误")
}

type WxRefundReq struct {
	Appid          string `xml:"appid"`          //公众账号ID
	Mch_id         string `xml:"mch_id"`         //商户号
	Nonce_str      string `xml:"nonce_str"`      //随机字符串
	Sign           string `xml:"sign"`           //签名
	Transaction_id string `xml:"transaction_id"` //商品描述
	Out_refund_no  string `xml:"out_refund_no"`  //交易类型
	Total_fee      int    `xml:"total_fee"`      //总金额
	Refund_fee     int    `xml:"refund_fee"`     //tuikuan金额
	Refund_desc    string `xml:"refund_desc"`    //通知地址
}

type WxRefundResp struct {
	Return_code    string `xml:"return_code"`
	Return_msg     string `xml:"return_msg"`
	Result_code    string `xml:"result_code"`
	Appid          string `xml:"appid"`
	Mch_id         string `xml:"mch_id"`
	Nonce_str      string `xml:"nonce_str"`
	Sign           string `xml:"sign"`
	Transaction_id string `xml:"transaction_id"`
	Out_trade_no   string `xml:"out_trade_no"`
	Out_refund_no  string `xml:"out_refund_no"`
	Refund_id      string `xml:"refund_id"`
	Refund_fee     int    `xml:"refund_fee"`
	Total_fee      int    `xml:"total_fee"`
	Cash_fee       int    `xml:"cash_fee"`
}

func WxRefund(mid, money string) error {
	md := models.Query(`select * from mt_member_money_detail where id=` + mid)[0]
	var yourReq WxRefundReq

	yourReq.Appid = fmt.Sprint(md["appid"])
	yourReq.Mch_id = fmt.Sprint(md["mch_id"])
	yourReq.Nonce_str = sword.RandStr(32)
	yourReq.Transaction_id = fmt.Sprint(md["transaction_id"])
	yourReq.Out_refund_no = sword.RandStr(32)
	totalfee, _ := strconv.Atoi(fmt.Sprint(md["total_fee"]))
	yourReq.Total_fee = totalfee

	moneyArr := strings.Split(money, ".")
	if len(moneyArr) == 1 {
		money = money + "00"
	} else {
		mInt := moneyArr[0]
		mFloat := moneyArr[1]
		length := len(mFloat)
		if length == 1 {
			money = mInt + mFloat + "0"
		} else if length == 2 {
			money = mInt + mFloat
		} else {
			money = mInt + mFloat[:2]
		}
	}
	moneyi, _ := strconv.Atoi(money)
	yourReq.Refund_fee = moneyi
	// yourReq.Refund_fee = 1
	yourReq.Refund_desc = `商品库存不足`
	// yourReq.Notify_url = models.Urlc + "/admin/wx_refund_callback"

	var m = make(map[string]interface{})
	m["appid"] = yourReq.Appid
	m["mch_id"] = yourReq.Mch_id
	m["nonce_str"] = yourReq.Nonce_str
	m["transaction_id"] = yourReq.Transaction_id
	m["out_refund_no"] = yourReq.Out_refund_no
	m["total_fee"] = yourReq.Total_fee
	m["refund_fee"] = yourReq.Refund_fee
	m["refund_desc"] = yourReq.Refund_desc
	// m["notify_url"] = yourReq.Notify_url

	yourReq.Sign = wxpayCalcSign(m, models.WxPay_secret) //这个key 微信商户平台(pay.weixin.qq.com)-->账户中心-->账户设置-->API安全

	bytes_req, err := xml.Marshal(yourReq)
	if err != nil {
		beego.Debug("转换为xml错误:", err)
		return err
	}
	str_req := strings.Replace(string(bytes_req), "WxRefundReq", "xml", -1) //fmt.Println("转换为xml--------", str_req)

	bytes_req = []byte(str_req) //发送unified order请求
	req, err := http.NewRequest("POST", "https://api.mch.weixin.qq.com/secapi/pay/refund", bytes.NewReader(bytes_req))
	if err != nil {
		beego.Debug("New Http Request发生错误，原因:", err)
		return err
	}
	req.Header.Set("Accept", "application/xml")
	//这里的http header的设置是必须设置的.
	req.Header.Set("Content-Type", "application/xml;charset=utf-8")
	client, err := NewTLSHttpClient("cert/apiclient_cert.pem", "cert/apiclient_key.pem")
	if err != nil {
		beego.Debug(err)
		return err
	}
	resp, _err := client.Do(req)

	if _err != nil {
		beego.Debug("请求微信支付退款接口发送错误, 原因:", _err)
		return _err
	}
	//------------------到这里统一下单接口就已经执行完成了-------------------
	respBytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		beego.Debug("解析返回body错误", err)
		return err
	}
	xmlResp := WxRefundResp{}
	_err = xml.Unmarshal(respBytes, &xmlResp)
	//处理return code.
	if xmlResp.Return_code == "FAIL" {
		beego.Debug("微信支付统一下单不成功，原因:", xmlResp.Return_msg, " str_req-->", str_req)
		return errors.New(xmlResp.Return_msg)
	}
	if err := models.Exec(fmt.Sprintf(`insert into mt_member_money_detail (uid,type,money,oid,addtime,return_code,transaction_id,nonce_str,sign,total_fee,
		out_refund_no,refund_fee,refund_id,cash_fee,paytype) values ('%v','%v','%v','%v','%v','%v','%v','%v','%v','%v','%v','%v', '%v','%v',2)`,
		md["uid"], 6, money, md["oid"], sword.Gettimes(""), xmlResp.Return_code, xmlResp.Transaction_id, xmlResp.Nonce_str, xmlResp.Sign,
		xmlResp.Total_fee, xmlResp.Out_refund_no, xmlResp.Refund_fee, xmlResp.Refund_id, xmlResp.Cash_fee)); err != nil {
		beego.Debug(err)
		return err
	}
	return nil
}

type WXRefundNotifyReq struct {
	Return_code string `xml:"return_code"`
	Return_msg  string `xml:"return_msg"`
	Appid       string `xml:"appid"`
	Mch_id      string `xml:"mch_id"`
	Nonce_str   string `xml:"nonce_str"`
	Req_info    string `xml:"req_info"`
}

func AES_256_ECB_D(reqinfo, secret string) ([]byte, error) {
	dreqinfo, err := base64.StdEncoding.DecodeString(reqinfo)
	if err != nil {
		beego.Debug(err)
		return nil, err
	}
	aes256, err := aes.NewCipher([]byte(secret))
	if err != nil {
		beego.Debug(err)
		return nil, err
	}
	aes256.Decrypt(dreqinfo, dreqinfo)
	return dreqinfo, err
}
func NewTLSHttpClient(certFile, keyFile string) (httpClient *http.Client, err error) {
	cert, err := tls.LoadX509KeyPair(certFile, keyFile)
	if err != nil {
		return
	}
	tlsConfig := &tls.Config{
		Certificates: []tls.Certificate{cert},
	}

	httpClient = &http.Client{
		Transport: &http.Transport{
			Proxy: http.ProxyFromEnvironment,
			Dial: (&net.Dialer{
				Timeout:   30 * time.Second,
				KeepAlive: 30 * time.Second,
			}).Dial,
			TLSHandshakeTimeout: 10 * time.Second,
			TLSClientConfig:     tlsConfig,
		},
		Timeout: 60 * time.Second,
	}
	return
}
func AlipayRefund(mid, money string) error {
	md := models.Query(`select * from mt_member_money_detail where id=` + mid)[0]
	var client = alipay.New(Alipay_appId, string(Alipay_aliPublicKey), string(Alipay_privateKey), true)
	//var client = alipay.New(Alipay_appId, Alipay_partnerId, Alipay_aliPublicKey, Alipay_privateKey, true)
	var p = alipay.AliPayTradeRefund{}
	p.OutTradeNo = fmt.Sprint(md["outtradeno"])
	p.RefundAmount = money
	// p.RefundAmount = "0.01"
	p.RefundReason = `商品库存不足`
	p.OutRequestNo = sword.RandStr(32)
	res, err := client.TradeRefund(p)
	if err != nil {
		beego.Debug(err)
		return err
	} else {
		if !res.IsSuccess() {
			return errors.New("退款失败")
		}
		info := res.AliPayTradeRefund
		if err := models.Exec(fmt.Sprintf(`insert into mt_member_money_detail (uid,type,money,oid,addtime,outtradeno,
		refund_fee,refund_id,paytype,refund_reason) values ('%v',6,'%v','%v','%v','%v','%v','%v',3,'%v')`, md["uid"], money, md["oid"],
			sword.Gettimes(""), info.OutTradeNo, info.RefundFee, p.OutRequestNo, p.RefundReason)); err != nil {
			beego.Debug(err)
			return err
		}
		return nil
	}
}
